#include "SystemClockSynchronizer.h"
#include "Decoder.h"

double SystemClockSynchronizer::clock() {
    std::lock_guard<std::mutex> lock(m_mutex);
    double currentTime = m_accumulatedTime;
    if (m_playing && !m_paused) {
        // 计算从上次开始播放到现在经过的时间，乘上播放速率
        auto now = std::chrono::steady_clock::now();
        double dt = std::chrono::duration_cast<std::chrono::duration<double>>(now - m_startTime).count();
        currentTime += dt * m_speed;
    }
    // 如果设置了视频总长度，则不超过最大时间
    if (m_maxDuration > 0.0 && currentTime > m_maxDuration) {
        currentTime = m_maxDuration;
    }
    return currentTime;
}

void SystemClockSynchronizer::pause() {
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_playing && !m_paused) {
        // 更新累计时间，并进入暂停状态
        auto now = std::chrono::steady_clock::now();
        double dt = std::chrono::duration_cast<std::chrono::duration<double>>(now - m_startTime).count();
        m_accumulatedTime += dt * m_speed;
        m_paused = true;
    }
}

void SystemClockSynchronizer::resume() {
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_playing && m_paused) {
        // 记录新的开始时间，并退出暂停状态
        m_startTime = std::chrono::steady_clock::now();
        m_paused = false;
    }
}

void SystemClockSynchronizer::start()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_playing = true;
    m_paused = false;
    m_accumulatedTime = 0.0;
    m_startTime = std::chrono::steady_clock::now();
}

void SystemClockSynchronizer::seek(double timepoint) {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_accumulatedTime = timepoint;
    // 如果处于播放状态且未暂停，则从当前时间重新计时
    if (m_playing && !m_paused) {
        m_startTime = std::chrono::steady_clock::now();
    }

    if(m_decoder && m_decoder->isRunning()) {
        m_decoder->seek(timepoint);
    }
}

void SystemClockSynchronizer::setPresentSpeed(double speed) {
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_playing && !m_paused) {
        // 切换播放速率时，需要先更新累计时间，否则会导致时间跳跃
        auto now = std::chrono::steady_clock::now();
        double dt = std::chrono::duration_cast<std::chrono::duration<double>>(now - m_startTime).count();
        m_accumulatedTime += dt * m_speed;
        m_startTime = now;
    }
    m_speed = speed;
}

Decoder *SystemClockSynchronizer::decoder() const
{
    return m_decoder;
}

void SystemClockSynchronizer::setDecoder(Decoder *newDecoder)
{
    if (m_decoder == newDecoder)
        return;
    m_decoder = newDecoder;
    emit decoderChanged();
}
